1
效能差距:為何要延伸 NumPy?
AI018Lesson 5
00:00

雖然 NumPy 建立在 C 語言之上,但某些運算密集型的演算法會遭遇 向量化壁壘。這發生在 Python 的動態特性所帶來的固有延遲,超過了高階抽象的好處時。

1. 編譯器稅與封裝

標準 Python 迴圈中的每一次迭代都涉及動態類型檢查和參考計數。即使使用 NumPy 的標量,將原始的 C 資料「封裝」成 Python 物件也會造成函式如 $\text{logit}(p) = \log(p/(1-p))$ 的巨大瓶頸。在 C 語言中處理邊界情況快得多:

>>> logit(0) -> -inf
>>> logit(1) -> inf
>>> logit(2) -> nan
>>> logit(-2) -> nan

2. 中間陣列膨脹

純粹的 NumPy 表達式會為每個子運算建立暫時性的記憶體緩衝區。透過 C-API 進行擴展可實現 核心融合,即在單一資料掃描過程中完成 logit 變換,而無需額外的記憶體開銷。

3. 空間相依性

涉及鄰近存取模式的操作,例如二維濾波器:

$$B(I, J) = A(I, J) + (A(I-1, J) + A(I+1, J) + A(I, J-1) + A(I, J+1)) \cdot 0.5D0 + (A(I-1, J-1) + A(I-1, J+1) + A(I+1, J-1) + A(I+1, J+1)) \cdot 0.25D0$$

若不重複複製記憶體,很難透過切片有效表達。C 擴充模組則可直接進行對齊快取的指標運算。

main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>